package com.asa.voice.mp3.asa;

import java.io.IOException;

import com.asa.voice.mp3.asa.decoder.Header;
import com.asa.voice.mp3.asa.decoder.IAudio;
import com.asa.voice.mp3.asa.decoder.ID3Tag;
import com.asa.voice.mp3.asa.decoder.Layer1;
import com.asa.voice.mp3.asa.decoder.Layer2;
import com.asa.voice.mp3.asa.decoder.Layer3;
import com.asa.voice.mp3.asa.instream.BuffRandReadFile;
import com.asa.voice.mp3.asa.instream.BuffRandReadURL;
import com.asa.voice.mp3.asa.instream.MultiplexAudio;
import com.asa.voice.mp3.asa.instream.RandomRead;

public class PlayBack {
  private byte[] buf;
  
  private final int BUFLEN = 8192;
  
  private boolean eof;
  
  private boolean paused;
  
  private RandomRead instream;
  
  private ID3Tag id3tag;
  
  private int off;
  
  private int maxOff;
  
  private Header header;
  
  private IAudio audio;
  
  public PlayBack(IAudio paramIAudio) {
    this.audio = paramIAudio;
    this.header = new Header();
    this.id3tag = new ID3Tag();
    this.buf = new byte[8192];
  }
  
  public boolean pause() {
    this.audio.start(this.paused);
    if (this.paused)
      synchronized (this) {
        notify();
      }  
    this.paused = !this.paused;
    return this.paused;
  }
  
  public void stop() {
    this.eof = true;
    synchronized (this) {
      notify();
    } 
    if (this.instream != null)
      this.instream.close(); 
  }
  
  public void close() {
    if (this.id3tag != null)
      this.id3tag.clear(); 
    if (this.audio != null)
      this.audio.close(); 
    if (this.instream != null)
      this.instream.close(); 
  }
  
  public boolean open(String paramString1, String paramString2) throws IOException {
    this.maxOff = this.off = 0;
    this.paused = this.eof = false;
    boolean bool = false;
    String str = paramString1.toLowerCase();
    if (str.startsWith("http://") && str.endsWith(".mp3")) {
      this.instream = (RandomRead)new BuffRandReadURL(this.audio);
    } else if (str.endsWith(".mp3")) {
      this.instream = (RandomRead)new BuffRandReadFile();
      bool = true;
    } else if (str.endsWith(".dat") || str.endsWith(".vob")) {
      this.instream = (RandomRead)new MultiplexAudio();
    } else {
      System.err.println("Invalid File Format.");
      return false;
    } 
    if (!this.instream.open(paramString1, paramString2))
      return false; 
    int i = parseTag(bool);
    if (i == -1)
      return false; 
    this.header.initialize(this.instream.length() - i, this.instream.getDuration());
    nextHeader();
    if (this.eof)
      return false; 
    if (this.audio != null && paramString2 != null) {
      String[] arrayOfString = paramString2.split(" ");
      if (arrayOfString.length >= 2) {
        this.id3tag.settTitle(arrayOfString[0]);
        this.id3tag.settArtist(arrayOfString[1]);
      } 
    } 
    if (this.audio != null && !this.audio.open(this.header, this.id3tag.getArtist()))
      return false; 
    return true;
  }
  
  private int parseTag(boolean paramBoolean) throws IOException {
    int i = 0;
    if (paramBoolean && this.instream.seek(this.instream.length() - 128L - 32L)) {
      if (this.instream.read(this.buf, 0, 160) == 160) {
        if (this.id3tag.checkID3V1(this.buf, 32)) {
          i = 128;
          this.id3tag.parseID3V1(this.buf, 32);
        } 
      } else {
        return -1;
      } 
      this.instream.seek(0L);
      i += this.id3tag.checkAPEtagFooter(this.buf, 0);
    } 
    if ((this.maxOff = this.instream.read(this.buf, 0, 8192)) <= 10) {
      this.eof = true;
      return -1;
    } 
    int j = this.id3tag.checkID3V2(this.buf, 0);
    i += j;
    if (j > this.maxOff) {
      byte[] arrayOfByte = new byte[j];
      System.arraycopy(this.buf, 0, arrayOfByte, 0, this.maxOff);
      j -= this.maxOff;
      if ((this.maxOff = this.instream.read(arrayOfByte, this.maxOff, j)) < j) {
        this.eof = true;
        return -1;
      } 
      this.id3tag.parseID3V2(arrayOfByte, 0, arrayOfByte.length);
      if ((this.maxOff = this.instream.read(this.buf, 0, 8192)) <= 4)
        this.eof = true; 
    } else if (j > 10) {
      this.id3tag.parseID3V2(this.buf, 0, j);
      this.off = j;
    } 
    return i;
  }
  
  public Header getHeader() {
    return this.header;
  }
  
  public ID3Tag getID3Tag() {
    return this.id3tag;
  }
  
  public boolean start(boolean paramBoolean) {
    Layer2 layer2 = null;
    Layer3 layer3 = null;
    Layer1 layer1 = null;
    byte b = 0;
    this.paused = false;
    switch (this.header.getLayer()) {
      case 1:
        layer1 = new Layer1(this.header, this.audio);
        break;
      case 2:
        layer2 = new Layer2(this.header, this.audio);
        break;
      case 3:
        layer3 = new Layer3(this.header, this.audio);
        break;
      default:
        return false;
    } 
    while (!this.eof) {
      this.off = layer3.decodeFrame(this.buf, this.off);
      if (paramBoolean && (++b & 0x7) == 0)
        this.header.printProgress(); 
      
      try {
    	  nextHeader();
          if (this.paused)
            synchronized (this) {
              while (this.paused && !this.eof)
                wait(); 
            }
		} catch (Exception e) {
			// TODO: handle exception
		}
      
        
    } 
    if (paramBoolean) {
      this.header.printProgress();
      System.out.println("\n");
    } 
    if (layer3 != null)
      layer3.close(); 
    return true;
  }
  
  private void nextHeader() throws IOException {
    byte b = 0;
    while (!this.eof && !this.header.syncFrame(this.buf, this.off, this.maxOff)) {
      this.off = this.header.offset();
      int i = this.maxOff - this.off;
      System.arraycopy(this.buf, this.off, this.buf, 0, i);
      this.maxOff = i + this.instream.read(this.buf, i, this.off);
      this.off = 0;
      b += 1;
      if (this.maxOff <= i || b > 65536)
        this.eof = true; 
    } 
    this.off = this.header.offset();
  }
}
